home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
pd
/
netz
/
term
/
extras
/
source
/
term-source.lha
/
termHotkeys.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-07
|
7KB
|
421 lines
/*
** termHotkeys.c
**
** Hotkey support routines.
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
enum { CX_TERMSCREENTOFRONT,CX_BUFFERSCREENTOFRONT,CX_SKIPDIALENTRY,CX_ABORTAREXX };
/* Asynchronous hotkey task. */
STATIC struct Process *CxProcess;
/* Hotkey(STRPTR Code,struct MsgPort *Port,LONG ID):
*
* A custom version of the amiga.lib supplied code.
*/
STATIC CxObj * __regargs
CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID)
{
CxObj *Filter;
if(Filter = CxFilter(Code))
{
CxObj *Sender;
if(Sender = CxSender(Port,ID))
{
CxObj *Translator;
AttachCxObj(Filter,Sender);
if(Translator = CxTranslate(NULL))
{
AttachCxObj(Filter,Translator);
if(!CxObjError(Filter))
return(Filter);
}
}
DeleteCxObjAll(Filter);
}
return(NULL);
}
/* CreateBroker(struct MsgPort *CxPort):
*
* Set up a CxObj commodity broker.
*/
STATIC CxObj * __regargs
CreateBroker(struct MsgPort *CxPort)
{
CxObj *Broker;
/* Set the commodity priority. */
NewTermBroker . nb_Pri = Hotkeys . CommodityPriority;
/* Create the broker. */
if(Broker = CxBroker(&NewTermBroker,NULL))
{
/* Add the hotkeys. */
AttachCxObj(Broker,CustomHotKey(Hotkeys . termScreenToFront, CxPort,CX_TERMSCREENTOFRONT));
AttachCxObj(Broker,CustomHotKey(Hotkeys . BufferScreenToFront, CxPort,CX_BUFFERSCREENTOFRONT));
AttachCxObj(Broker,CustomHotKey(Hotkeys . SkipDialEntry, CxPort,CX_SKIPDIALENTRY));
AttachCxObj(Broker,CustomHotKey(Hotkeys . AbortARexx, CxPort,CX_ABORTAREXX));
/* Did an error show up? */
if(!CxObjError(Broker))
{
/* Broker has been added, now activate it. */
ActivateCxObj(Broker,Hotkeys . HotkeysEnabled);
return(Broker);
}
DeleteCxObjAll(Broker);
}
return(NULL);
}
/* TermCxServer():
*
* Asynchronous hotkey server.
*/
STATIC VOID __saveds
TermCxServer(VOID)
{
CxObj *Broker;
struct MsgPort *CxPort;
CxMsg *Message;
/* Create a reply port. */
if(CxPort = CreateMsgPort())
{
/* Add the port to the public list. */
CxPort -> mp_Node . ln_Name = NewTermBroker . nb_Name;
AddPort(CxPort);
/* Install the port. */
NewTermBroker . nb_Port = CxPort;
/* Create the broker. */
if(Broker = CreateBroker(CxPort))
{
ULONG SignalSet;
BYTE Terminated = FALSE;
/* Signal father task that we're done. */
Signal(ThisProcess,SIG_HANDSHAKE);
/* Loop and loop... */
while(!Terminated)
{
/* Wait for some signal. */
SignalSet = Wait(SIG_KILL | SIG_RESET | PORTMASK(CxPort));
/* ^C aborts. */
if(SignalSet & SIG_KILL)
Terminated = TRUE;
/* ^D removes the broker and
* creates a new one.
*/
if(SignalSet & SIG_RESET)
{
DeleteCxObjAll(Broker);
Broker = CreateBroker(CxPort);
}
/* A commodity message. */
if(SignalSet & PORTMASK(CxPort))
{
ULONG MessageType,MessageID;
/* Remove all messages. */
while(Message = (CxMsg *)GetMsg(CxPort))
{
/* Extract type and ID. */
MessageType = CxMsgID(Message);
MessageID = CxMsgType(Message);
ReplyMsg((struct Message *)Message);
/* Take a look at the type... */
switch(MessageID)
{
/* A hotkey was pressed. */
case CXM_IEVENT:
switch(MessageType)
{
case CX_TERMSCREENTOFRONT:
Forbid();
if(Window)
BumpWindow(TopWindow);
else
Signal(ThisProcess,SIGBREAKF_CTRL_F);
Permit();
break;
case CX_BUFFERSCREENTOFRONT:
LaunchBuffer();
break;
case CX_SKIPDIALENTRY:
Signal(ThisProcess,SIG_SKIP);
break;
case CX_ABORTAREXX:
if(InRexx)
Signal(ThisProcess,SIG_BREAK);
break;
}
break;
/* An internal commodity command. */
case CXM_COMMAND:
switch(MessageType)
{
case CXCMD_DISABLE:
ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = FALSE);
break;
case CXCMD_ENABLE:
ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = TRUE);
break;
}
break;
}
}
}
}
/* Remove the broker. */
DeleteCxObjAll(Broker);
}
/* Remove the port from the public list. */
RemPort(CxPort);
/* Remove all pendig messages. */
while(Message = (CxMsg *)GetMsg(CxPort))
ReplyMsg((struct Message *)Message);
/* Delete the reply port. */
DeleteMsgPort(CxPort);
}
Forbid();
/* Clear the task ID. */
CxProcess = NULL;
/* Signal father process that we're done. */
Signal(ThisProcess,SIG_HANDSHAKE);
}
/* ShutdownCx():
*
* Remove the hotkey task.
*/
VOID
ShutdownCx()
{
if(CxProcess)
{
Forbid();
Signal(CxProcess,SIG_KILL);
ClrSignal(SIG_HANDSHAKE);
Wait(SIG_HANDSHAKE);
Permit();
}
}
/* SetupCx():
*
* Create the hotkey task.
*/
BYTE
SetupCx()
{
/* If the task is already running, tell it to
* update the hotkey settings.
*/
if(CxProcess)
{
Signal(CxProcess,SIG_RESET);
return(TRUE);
}
else
{
Forbid();
if(CxProcess = (struct Process *)CreateNewProcTags(
NP_Entry, TermCxServer,
NP_Name, "term Hotkey Process",
NP_Priority, 0,
NP_StackSize, 8192,
NP_WindowPtr, -1,
TAG_END))
{
ClrSignal(SIG_HANDSHAKE);
Wait(SIG_HANDSHAKE);
}
Permit();
if(CxProcess)
return(TRUE);
}
return(FALSE);
}
/* LoadHotkeys(STRPTR Name,struct Hotkeys *Keys):
*
* Load the hotkey settings from a file.
*/
BYTE __regargs
LoadHotkeys(STRPTR Name,struct Hotkeys *Keys)
{
struct IFFHandle *Handle;
BYTE Success = FALSE;
struct StoredProperty *Prop;
struct TermInfo *TermInfo;
LONG Error = 0;
if(Handle = AllocIFF())
{
if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
{
InitIFFasDOS(Handle);
if(!(Error = OpenIFF(Handle,IFFF_READ)))
{
/* Collect version number ID if
* available.
*/
if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
{
/* The following line tells iffparse to stop at the
* very beginning of a `Type' chunk contained in a
* `TERM' FORM chunk.
*/
if(!(Error = StopChunk(Handle,ID_TERM,ID_HOTK)))
{
/* Parse the file... */
if(!ParseIFF(Handle,IFFPARSE_SCAN))
{
/* Did we get a version ID? */
if(Prop = FindProp(Handle,ID_TERM,ID_VERS))
{
TermInfo = (struct TermInfo *)Prop -> sp_Data;
if((TermInfo -> Version < CONFIG_FILE_VERSION) || (TermInfo -> Version == CONFIG_FILE_VERSION && TermInfo -> Revision < CONFIG_FILE_REVISION))
{
if(ReadChunkBytes(Handle,Keys,sizeof(struct HotkeysOld)) == sizeof(struct HotkeysOld))
{
strcpy(Keys -> AbortARexx,"lshift rshift escape");
Success = TRUE;
}
else
Error = IoErr();
}
else
{
if(ReadChunkBytes(Handle,Keys,sizeof(struct Hotkeys)) == sizeof(struct Hotkeys))
Success = TRUE;
else
Error = IoErr();
}
}
}
}
}
CloseIFF(Handle);
}
Close(Handle -> iff_Stream);
}
else
Error = IoErr();
FreeIFF(Handle);
}
else
Error = ERR_NO_MEM;
if(Error)
SetIoErr(Error);
return(Success);
}